package com.vrp3d.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vrp3d.common.enums.CommonEnum;
import com.vrp3d.common.enums.CommonExceptionEnum;
import com.vrp3d.common.enums.ShowroomStatusEnum;
import com.vrp3d.common.exceptions.CommonException;
import com.vrp3d.common.utils.ObjUtil;
import com.vrp3d.domain.dto.dist.DistForFrontDTO;
import com.vrp3d.domain.dto.showroom.*;
import com.vrp3d.domain.po.DistWithBLOBs;
import com.vrp3d.domain.po.Showroom;
import com.vrp3d.domain.po.ShowroomExample;
import com.vrp3d.mapper.ShowroomMapper;
import com.vrp3d.service.DistService;
import com.vrp3d.service.ShowroomService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;

/**
 * 展厅
 *
 * @author vrp3d
 */
@Slf4j
@Service
public class ShowroomServiceImpl extends AbsServiceImpl implements ShowroomService {

    @Autowired
    private DistService distService;

    @Autowired
    private ShowroomMapper showroomMapper;

    private ShowroomExample getExample() {
        return new ShowroomExample();
    }

    private ShowroomExample.Criteria getCriteria(ShowroomExample example) {
        return example.createCriteria();
    }

    @Override
    public Showroom selectByPrimaryKey(Integer id) {
        ShowroomExample example = getExample();
        ShowroomExample.Criteria criteria = getCriteria(example);
        criteria.andIdEqualTo(id);
        criteria.andStatusNotEqualTo(getDeletedStatus());
        List<Showroom> list = showroomMapper.selectByExample(example);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    @Override
    public Page<ShowroomListDTO> getShowroomList(Page<ShowroomListDTO> page, ShowroomSearchDTO search) {
        List<ShowroomListDTO> list = showroomMapper.getShowroomList(page, search);
        if (!CollectionUtils.isEmpty(list)) {
            for (ShowroomListDTO showroomListDTO : list) {
                DistWithBLOBs dist = distService.selectByPrimaryKey(showroomListDTO.getType());

                // 底图
                if (StringUtils.isNotBlank(dist.getIcon())) {
                    showroomListDTO.setPavilionBaseMap(dist.getIcon());
                }
                // 场景
                if (StringUtils.isNotBlank(dist.getRemarks())) {
                    showroomListDTO.setSceneFile(dist.getRemarks());
                }
                // 坐标
                if (StringUtils.isNotBlank(dist.getCoordinateInformation())) {
                    showroomListDTO.setCoordinateInformation(dist.getCoordinateInformation());
                }
            }
        }
        return page.setRecords(list);
    }

    @Override
    public void whetherTheNameOfTheExhibitionHall(String showroomName) {
        ShowroomExample example = getExample();
        ShowroomExample.Criteria criteria = getCriteria(example);
        criteria.andStatusNotEqualTo(ShowroomStatusEnum.DELETE.getMsgInteger());
        showroomName = showroomName.trim();
        criteria.andNameEqualTo(showroomName);
        List<Showroom> showrooms = showroomMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(showrooms) || StringUtils.isBlank(showroomName)) {
            throw new CommonException(CommonExceptionEnum.SHOWROOM_NAME_ALREADY_EXISTS);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void insertShowroom(ShowroomInsertDTO dto) {
        log.info("待新增展厅信息:{}", dto);

        // 检查名称是否可用
        String name = dto.getName().trim();
        whetherTheNameOfTheExhibitionHall(name);
        dto.setName(name);

        Showroom insert = new Showroom();
        BeanUtils.copyProperties(dto, insert);

        insert.setStatus(getNormalStatus());

        // 用户id
        Integer userId = getUser().getId();
        Date date = getNowTime();
        insert.setCreateId(userId);
        insert.setCreateTime(date);
        insert.setUpdateId(userId);
        insert.setUpdateTime(date);

        showroomMapper.insertSelective(insert);
    }

    @Override
    public void whetherTheNameOfTheExhibitionHallWhenUpdate(Integer id, String showroomName) {
        ShowroomExample example = getExample();
        ShowroomExample.Criteria criteria = getCriteria(example);
        criteria.andStatusNotEqualTo(ShowroomStatusEnum.DELETE.getMsgInteger());
        showroomName = showroomName.trim();
        criteria.andNameEqualTo(showroomName);
        criteria.andIdNotEqualTo(id);
        List<Showroom> showrooms = showroomMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(showrooms) || StringUtils.isBlank(showroomName)) {
            throw new CommonException(CommonExceptionEnum.SHOWROOM_NAME_ALREADY_EXISTS);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateShowroom(ShowroomUpdateDTO dto) {
        log.info("待修改信息:{}", dto);

        // 查询是否存在
        Integer id = dto.getId();
        Showroom showroom = selectByPrimaryKey(id);
        if (ObjUtil.isEmpty(showroom)) {
            throw new CommonException(CommonExceptionEnum.THE_EXHIBITION_HALL_DOES_NOT_EXIST);
        } else {
            // 检查名称是否可用
            String name = dto.getName().trim();
            whetherTheNameOfTheExhibitionHallWhenUpdate(id, name);
            dto.setName(name);

            Showroom update = new Showroom();
            BeanUtils.copyProperties(dto, update);

            // 修改人id
            update.setUpdateId(getUser().getId());

            // todo 确认业务逻辑 修改后的状态
            switch (ShowroomStatusEnum.getShowroomStatusEnum(showroom.getStatus())) {
                // 未提交的依旧是未提交,提交的设置为提交待审核?
                case NORMAL:
                case PENDING_REVIEW:
                    update.setStatus(ShowroomStatusEnum.NORMAL.getMsgInteger());
                    break;
                case EXAMINATION_PASSED:
                case AUDIT_NOT_PASSED:
                    update.setStatus(ShowroomStatusEnum.PENDING_REVIEW.getMsgInteger());
                    break;
                default:
                    break;
            }

            showroomMapper.updateByPrimaryKeySelective(update);
        }

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteShowroomById(Integer id) {
        // todo 权限判断,处理展位信息
        log.info("待删除展厅id:{}", id);

        Showroom showroom = selectByPrimaryKey(id);
        if (ObjUtil.isEmpty(showroom)) {
            throw new CommonException(CommonExceptionEnum.THE_EXHIBITION_HALL_DOES_NOT_EXIST);
        } else {
            // 软删除
            Showroom delete = new Showroom();
            delete.setId(id);
            delete.setStatus(getDeletedStatus());
            delete.setDeleteTime(getNowTime());
            showroomMapper.updateByPrimaryKeySelective(delete);
        }
    }

    @Override
    public void submitReview(Integer id) {
        // 查询是否存在
        Showroom showroom = selectByPrimaryKey(id);
        if (ObjUtil.isEmpty(showroom)) {
            throw new CommonException(CommonExceptionEnum.THE_EXHIBITION_HALL_DOES_NOT_EXIST);
        } else {
            int status = ShowroomStatusEnum.PENDING_REVIEW.getMsgInteger();
            // 根据不同状态判断处理
            switch (ShowroomStatusEnum.getShowroomStatusEnum(showroom.getStatus())) {
                // 未提交的依旧是未提交,提交的设置为提交待审核?
                case NORMAL:
                case AUDIT_NOT_PASSED:
                    break;
                case PENDING_REVIEW:
                    throw new CommonException(CommonExceptionEnum.SUBMITTED_FOR_REVIEW);
                case EXAMINATION_PASSED:
                    throw new CommonException(CommonExceptionEnum.THE_AUDIT_OF_THE_EXHIBITION_HALL_HAS_BEEN_PASSED);
                default:
                    break;
            }
            Showroom update = new Showroom();
            update.setId(id);
            update.setStatus(status);
            // 修改人id
            update.setUpdateId(getUser().getId());
            showroomMapper.updateByPrimaryKeySelective(update);
        }
    }

    @Override
    public List<DistForFrontDTO> getTypeList() {
        return distService.findListByTypeContainsSubordinates(CommonEnum.SHOWROOM_TYPE.getMsg());
    }

    @Override
    public Page<ShowroomListDTO> getShowroomListFront(Page<ShowroomListDTO> page, ShowroomSearchDTO search) {
        search.setStatus(ShowroomStatusEnum.EXAMINATION_PASSED.getMsgInteger());
        List<ShowroomListDTO> list = showroomMapper.getShowroomList(page, search);
        if (!CollectionUtils.isEmpty(list)) {
            for (ShowroomListDTO showroomListDTO : list) {
                DistWithBLOBs dist = distService.selectByPrimaryKey(showroomListDTO.getType());
                // 场景
                if (StringUtils.isNotBlank(dist.getRemarks())) {
                    showroomListDTO.setSceneFile(dist.getRemarks());
                }
            }
        }
        return page.setRecords(list);
    }

    @Override
    public void statusPass(ShowroomStatusPassDTO dto) {
        //判断展厅是否存在
        @NotNull(message = "展厅不能为空") Integer id = dto.getId();
        Showroom showroom = selectByPrimaryKey(dto.getStatus());
        if (ObjUtil.isEmpty(showroom)) {
            throw new CommonException(CommonExceptionEnum.THE_EXHIBITION_HALL_DOES_NOT_EXIST);
        } else {
            int status = ShowroomStatusEnum.NORMAL.getMsgInteger();
            //判断展厅状态是否为待审核状态
            switch (ShowroomStatusEnum.getShowroomStatusEnum(showroom.getStatus())) {
                case PENDING_REVIEW:
                case NORMAL:
                case DELETE:
                    log.info("展厅审核时，状态值异常，展厅id:{},状态值:{}", id, status);
                    throw new CommonException(CommonExceptionEnum.THE_AUDIT_STATUS_OF_THE_EXHIBITION_HALL_IS_DELETE);
                case EXAMINATION_PASSED:
                    log.info("审核通过");
                    break;
                case AUDIT_NOT_PASSED:
                    log.info("审核不通过");
                    throw new CommonException(CommonExceptionEnum.THE_AUDIT_OF_THE_EXHIBITION_HALL_HAS_NOT_BEEN_PASSED);
                default:
                    break;
            }
            //修改更新数据库
            Showroom update = new Showroom();
            update.setId(id);
            update.setUpdateId(dto.getId());
            update.setUpdateTime(getNowTime());
            update.setStatus(status);
            showroomMapper.updateByPrimaryKeySelective(update);
        }
    }


    @Override
    public Page<ShowroomListReviewDTO> getShowroomListReview(Page<ShowroomListReviewDTO> page, ShowroomListReviewDTO dto) {
        Showroom showroom = selectByPrimaryKey(dto.getStatus());
        if (ObjUtil.isEmpty(showroom)) {
            throw new CommonException(CommonExceptionEnum.THE_EXHIBITION_HALL_DOES_NOT_EXIST);
        }
        switch (ShowroomStatusEnum.getShowroomStatusEnum(showroom.getStatus())) {
            case NORMAL:
            case PENDING_REVIEW:
                log.info("展厅待审核");
            default:
                break;
        }
        dto.setStatus(ShowroomStatusEnum.PENDING_REVIEW.getMsgInteger());
        List<ShowroomListReviewDTO> list = showroomMapper.getShowroomListReview(page,dto);
        return page.setRecords(list);
    }
}

